<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件的 v-model 支持自定义的修饰符</title>
    <script src="../public/vue_3.2.36.js"></script>
  </head>
  <body>
    <template id="inp">
      <div>
        <input type="text" :value="modelValue" @input="emitValue" />
      </div>
    </template>
    <div id="app">
      <h1>组件的 v-model 支持自定义的修饰符</h1>
      <p>
        我们来创建一个自定义的修饰符 capitalize，它会自动将 v-model
        绑定输入的字符串值第一个字母转为大写：
      </p>
      <p>父组件中的双向绑定值：{{myText}}</p>
      MyComponent组件:<my-component v-model.capitalize="myText"></my-component>
      <hr>
      <pre>
        对于又有参数又有修饰符的 v-model 绑定，生成的 prop 名将是 arg + "Modifiers"。举例来说：
        
        template
        &lt;MyComponent v-model:title.capitalize="myText"&gt;
        相应的声明应该是：

        js
        const props = defineProps(['title', 'titleModifiers'])
        defineEmits(['update:title'])

        console.log(props.titleModifiers) // { capitalize: true }
      </pre>
    </div>

    <script>
      const { createApp, toRefs, ref } = Vue;
      const MyComponent = {
        template: "#inp",
        props: {
          modelValue: String,
          modelModifiers: { default: () => ({}) },
          //组件的 v-model 上所添加的修饰符，可以通过 modelModifiers prop 在组件内访问到。在下面的组件中，我们声明了 modelModifiers 这个 prop，它的默认值是一个空对象：
        },
        emits: ["update:modelValue"],
        setup(props, { emit }) {
          console.log(props);
          function emitValue(e) {
            let value = e.target.value;
            if (props.modelModifiers.capitalize) {
              value = value.charAt(0).toUpperCase() + value.slice(1);
            }
            emit("update:modelValue", value);
          }
          return {
            emitValue,
            ...toRefs(props),
          };
        },
      };
      const app = createApp({
        components: {
          MyComponent,
        },
        setup() {
          const myText = ref("hhh");
          return {
            myText,
          };
        },
      });
      app.mount("#app");
    </script>
  </body>
</html>
